/*
    The I Ching (the Book of Changes) plasmoid.
    Copyright (C) 2002-2009 Jean Pierre Charalambos.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "trigram.h"

Trigram::Trigram() {
    for ( int i=0; i <3; i++ )
        components.append ( new Line() );
    generate();
    for ( int i=0; i <3; i++ )
        connect ( components.at ( i ), SIGNAL ( changed() ), SLOT ( setId() ) );
}

Trigram::Trigram ( int anId ) {
    for ( int i=0; i <3; i++ )
        components.append ( new Line() );
    adjust ( anId );
    for ( int i=0; i <3; i++ )
        connect ( components.at ( i ), SIGNAL ( changed() ), SLOT ( setId() ) );
}

Trigram::Trigram ( Line * a, Line * b, Line * c ) {
    components.append ( a );
    components.append ( b );
    components.append ( c );
    generate();
    for ( int i=0; i <3; i++ )
        connect ( components.at ( i ), SIGNAL ( changed() ), SLOT ( setId() ) );
}

Trigram::Trigram ( QVector<int> vec ) {
    if ( vec.size() < 3 )
        vec.resize ( 3 );
    Trigram ( vec.at ( 0 ), vec.at ( 1 ), vec.at ( 2 ) );
}

Trigram::Trigram ( int a, int b, int c ) {
    components.append ( new Line ( a ) );
    components.append ( new Line ( b ) );
    components.append ( new Line ( c ) );
    generate ( );
    for ( int i=0; i <3; i++ )
        connect ( components.at ( i ), SIGNAL ( changed() ), SLOT ( setId() ) );
}

void Trigram::generate() {
    if ( ( components.at ( 0 )->getId() % 2 ) == 1 && ( components.at ( 1 )->getId() % 2 ) == 1 && ( components.at ( 2 )->getId() % 2 ) == 1 )
        id = 1; // Ch'ien
    if ( ( components.at ( 0 )->getId() % 2 ) == 1 && ( components.at ( 1 )->getId() % 2 ) == 0 && ( components.at ( 2 )->getId() % 2 ) == 0 )
        id = 2; // Chen
    if ( ( components.at ( 0 )->getId() % 2 ) == 0 && ( components.at ( 1 )->getId() % 2 ) == 1 && ( components.at ( 2 )->getId() % 2 ) == 0 )
        id = 3; // Kan
    if ( ( components.at ( 0 )->getId() % 2 ) == 0 && ( components.at ( 1 )->getId() % 2 ) == 0 && ( components.at ( 2 )->getId() % 2 ) == 1 )
        id = 4; // Ken
    if ( ( components.at ( 0 )->getId() % 2 ) == 0 && ( components.at ( 1 )->getId() % 2 ) == 0 && ( components.at ( 2 )->getId() % 2 ) == 0 )
        id = 5; // K'un
    if ( ( components.at ( 0 )->getId() % 2 ) == 0 && ( components.at ( 1 )->getId() % 2 ) == 1 && ( components.at ( 2 )->getId() % 2 ) == 1 )
        id = 6; // Sun
    if ( ( components.at ( 0 )->getId() % 2 ) == 1 && ( components.at ( 1 )->getId() % 2 ) == 0 && ( components.at ( 2 )->getId() % 2 ) == 1 )
        id = 7; // Li
    if ( ( components.at ( 0 )->getId() % 2 ) == 1 && ( components.at ( 1 )->getId() % 2 ) == 1 && ( components.at ( 2 )->getId() % 2 ) == 0 )
        id = 8; // Tui
    setName();
}

void Trigram::adjust ( int i ) {
    id = i-1;
    id = id%8;
    id ++;
    switch ( id ) {
    case 1://chien
        components[ 0 ]->adjust ( 1 );
        components[ 1 ]->adjust ( 1 );
        components[ 2 ]->adjust ( 1 );
        break;
    case 2://chen
        components[ 0 ]->adjust ( 1 );
        components[ 1 ]->adjust ( 2 );
        components[ 2 ]->adjust ( 2 );
        break;
    case 3://kan
        components[ 0 ]->adjust ( 2 );
        components[ 1 ]->adjust ( 1 );
        components[ 2 ]->adjust ( 2 );
        break;
    case 4://ken
        components[ 0 ]->adjust ( 2 );
        components[ 1 ]->adjust ( 2 );
        components[ 2 ]->adjust ( 1 );
        break;
    case 5://kun
        components[ 0 ]->adjust ( 2 );
        components[ 1 ]->adjust ( 2 );
        components[ 2 ]->adjust ( 2 );
        break;
    case 6://sun
        components[ 0 ]->adjust ( 2 );
        components[ 1 ]->adjust ( 1 );
        components[ 2 ]->adjust ( 1 );
        break;
    case 7://li
        components[ 0 ]->adjust ( 1 );
        components[ 1 ]->adjust ( 2 );
        components[ 2 ]->adjust ( 1 );
        break;
    case 8://tui
        components[ 0 ]->adjust ( 1 );
        components[ 1 ]->adjust ( 1 );
        components[ 2 ]->adjust ( 2 );
        break;
    }
    setName();
}

void Trigram::setName() {
    switch ( id ) {
    case 1:
        name = "Ch'ien";
        eng_name = "The Creative";
        family = "Father";
        image = "Heaven" ;
        break;
    case 2:
        name = "Chen";
        eng_name = "The Arousing";
        family = "Eldest son";
        image = "Thunder" ;
        break;
    case 3:
        name = "K'an";
        eng_name = "The Abysmal";
        family = "Second son";
        image = "Water" ;
        break;
    case 4:
        name = "Ken";
        eng_name = "Keeping still";
        family = "Youngest son";
        image = "Mountain" ;
        break;
    case 5:
        name = "K'un";
        eng_name = "The Receptive";
        family = "Mother";
        image = "Earth" ;
        break;
    case 6:
        name = "Sun";
        eng_name = "The Gentle";
        family = "Eldest daughter";
        image = "Wind" ;
        break;
    case 7:
        name = "Li";
        eng_name = "The Clinging";
        family = "Second Daughter";
        image = "Sun" ;
        break;
    case 8:
        name = "Tui";
        eng_name = "The Joyous";
        family = "Youngest daughter";
        image = "Lake" ;
        break;
    }
}

#include "trigram.moc"
